
Skt.SketchpadController = L.Class.extend({
	
	includes: L.Mixin.Events,
	
	events: [
         'groupsManagerInvitationUpdate',
         'groupUpdate',
         'groupsUpdated',
         'roomListUpdate',
         'roomModeratorUpdate',
         'roomObjectAction',
         'editingEnabledChanged',
         'editorToolChanged',
         'editorCanvasesUpdated',
         'editorCurrentCanvasChanged',
         'editorCanvasChanged',
         'teacherTrackerUpdate',
         'usersManagerUsersUpdate',
         'usersManagerRequestsUpdate'
     ],

	initialize: function(
			basePath,
			subjectVersion,
			activity,
			user,
			options 
	) {
		L.Util.setOptions(this, options);
		
		if ( typeof this.options.coupling === 'undefined' )
			this.options.coupling = { enabled: false };

		if ( typeof this.options.useUI === 'undefined' )
			this.options.useUI = true;
		
		this._basePath = basePath;
		this._subjectVersion = subjectVersion;
		this._activity = activity;
		this._user = user;

		// copy-paste vars
		this._copiedElements = null;
		this._copiedBackground = null;
		
		this._uniqueIdManager = new Skt.UniqueIdManager(this);
		
		this._usersManager = new Skt.UsersManager(this);
		this._usersManager.on('usersUpdate', this._usersManagerUsersUpdate, this);
		this._usersManager.on('requestsUpdate', this._usersManagerRequestsUpdate, this);
		
		this._groupsManager = new Skt.GroupsManager(this);
		this._groupsManager.on('invitationUpdate', this._invitationUpdate, this);
		this._groupsManager.on('groupUpdate', this._groupUpdate, this);
		this._groupsManager.on('groupsUpdated', this._groupsUpdated, this);
		this._groupsManager.on('groupRoomListUpdate', this._roomListUpdate, this);
		this._groupsManager.on('roomModeratorUpdate', this._roomModeratorUpdate, this);
		
		this._roomLists = {};
		for ( var type in Skt.SlideType ) {
			if ( Skt.SlideType[type] != Skt.SlideType.GROUP ) {
				var roomList = this._roomLists[Skt.SlideType[type]] = new Skt.RoomList(Skt.SlideType[type], this, null);
				roomList.on('update', this._roomListUpdate, this);
				roomList.on('roomModeratorUpdate', this._roomModeratorUpdate, this);
				roomList.on('roomObjectAction', this._roomObjectAction, this);
			}
		}
		
		if ( this.options.useUI ) {
			this._editor = new Skt.Editor(this, options);
			this._editor.on('editingEnabledChanged', this._editingEnabledChanged, this);
			this._editor.on('toolChanged', this._editorToolChanged, this);
			this._editor.on('canvasesUpdated', this._editorCanvasesUpdated, this);
			this._editor.on('currentCanvasChanged', this._editorCurrentCanvasChanged, this);
			this._editor.on('currentCanvasChanged', this._handleCurrentCanvasChanged, this);
			this._editor.on('canvasChanged', this._editorCanvasChanged, this);
			
			this._teacherTracker = new Skt.TeacherTracker(this);
			this._teacherTracker.on('update', this._teacherTrackerUpdate, this);
		}
	},
	
	findRoomById: function(roomId) {
		var roomList = this.findRoomListByRoomId(roomId);
		if ( roomList != null )
			return roomList.findRoomById(roomId);
		else
			return null;
	},
	
	findRoomListByRoomId: function(roomId) {
		var groups = this._groupsManager.getAllGroups();

		for (var k = 0; k < groups.length; ++k)
			if ( groups[k].getRoomList().containsRoom(roomId) )
				return groups[k].getRoomList();
		
		for (var type in Skt.SlideType)
			if ( Skt.SlideType[type] != Skt.SlideType.GROUP 
					&& this._roomLists[Skt.SlideType[type]].containsRoom(roomId) )
				return this._roomLists[Skt.SlideType[type]];
		
		return null;
	},
	
	findRoomListByType: function(type, groupId) {
		if ( type == Skt.SlideType.GROUP && groupId == null ) {
			console.log('[ERROR] SketchpadController.findRoomListByType buscando roomlist grupal con groupId nulo');
			return null;
		}
		
		if ( type == Skt.SlideType.GROUP )
			return this._groupsManager.findGroup(groupId).getRoomList();
		
		return this._roomLists[type];		
	},
	
	eachRoom : function(fn, context) {
		var groups = this._groupsManager.getAllGroups();

		for (var k = 0; k < groups.length; ++k)
			groups[k].getRoomList().eachRoom(fn, context);
		
		for (var type in Skt.SlideType)
			if ( Skt.SlideType[type] != Skt.SlideType.GROUP )
				this._roomLists[Skt.SlideType[type]].eachRoom(fn, context);
	},

	addRoom : function(id, type, author, groupId, index) {
		var roomList = this.findRoomListByType(type, groupId);
		if ( roomList != null )
			roomList.addRoom(Number(id), Number(author.id), index);
		else
			console.log("[ERROR] SketchpadController.addRoom no se encuentra roomList para [" + id + ","+ type + ","+ author + ","+ groupId + "," + index + "]" );
	},

	removeRoom : function(roomId, author) {
		var room = this.findRoomById(Number(roomId));
		if ( room != null && room.getRoomModerator().canEdit(author) )
			room.getRoomList().removeRoom(Number(roomId));
		else
			console.log("[ERROR] SketchpadController.removeRoom no se encuentra room con roomId " + roomId);
	},

	copyRoom : function(roomId) {
		var room = this.findRoomById(roomId);
		
		if ( room != null ) {
			var elements = [];
			room.eachObject(function(obj) {
				elements.push(L.Util.extend({}, obj));
			});
			
			this._copiedElements = elements;
			this._copiedBackground = room.getBackground();
		} else
			console.log("[ERROR] SketchpadController.copyRoom no se encuentra room con roomId " + roomId);
	},

	pasteRoom : function(roomId, author) {
		if ( !this._copiedElements ) {
			console.log("[WARNING] SketchpadController.pasteRoom no encontro elementos copiados para pegar");
			return;
		}
		
		var room = this.findRoomById(roomId);
		if ( room != null && room.getRoomModerator().canEdit(author) ) {
			var elements = this._copiedElements;
			for (var i = 0, n = elements.length; i < n; i++) {
				// asignar un nuevo id a elemento copiado
				uniqueId(elements[i], true);
				// room.addObject(elements[i]);
				room.addCommand('addObject', { object : elements[i] });
			}
			room.addCommand("setBackground", {background: this._copiedBackground});
			return true;
		} else 
			return false;
	},
	
	getCurrentRoom: function() {
		var canvas = this._editor.getCurrentCanvas();
		if ( canvas != null )
			return canvas.getRoom();
		return null;
	},
	
	nextId: function() {
		console.log(Skt.sketchpad.getUniqueIdManager());
		return Skt.sketchpad.getUniqueIdManager().getNextId();
	},
	
	_handleCurrentCanvasChanged: function(params) {
		var newCanvas = params.newCanvas;
		var oldCanvas = params.oldCanvas;
		
		if ( oldCanvas != null )
			oldCanvas.getRoom().getRoomModerator().userLeave(this._user.id);

		if ( newCanvas != null ) 
			newCanvas.getRoom().getRoomModerator().userJoin(this._user.id); 
	},

	getBasePath: function() { return this._basePath; },
	getUser: function() { return this._user; },
	getSubjectVersion: function() { return this._subjectVersion; },
	getActivity: function() { return this._activity; },
	getOptions: function() { return this.options; },
	getGroupsManager: function() { return this._groupsManager; },
	getRoomLists: function() { return this._roomLists; },
	getTeacherTracker: function() { return this._teacherTracker; },
	getEditor: function() { return this._editor; },
	getUsersManager: function() { return this._usersManager; },
	getUniqueIdManager: function() { return this._uniqueIdManager; },

	_invitationUpdate: function(params) { this.fire('groupsManagerInvitationUpdate', params); },
	_groupUpdate: function(params) { this.fire('groupUpdate', params); },
	_groupsUpdated: function(params) { this.fire('groupsUpdated', params); },
	_roomListUpdate: function(params) { this.fire('roomListUpdate', params); },
	_roomModeratorUpdate: function(params) { this.fire('roomModeratorUpdate', params); },
	_roomObjectAction: function(params) { this.fire('roomObjectAction', params); },
	_editingEnabledChanged: function(params) { this.fire('editingEnabledChanged', params); },
	_editorToolChanged: function(params) { this.fire('editorToolChanged', params); },
	_editorCanvasesUpdated: function(params) { this.fire('editorCanvasesUpdated', params); },
	_editorCurrentCanvasChanged: function(params) { this.fire('editorCurrentCanvasChanged', params); },
	_editorCanvasChanged: function(params) { this.fire('editorCanvasChanged', params); },
	_teacherTrackerUpdate: function(params) { this.fire('teacherTrackerUpdate', params); },
	_usersManagerUsersUpdate: function(params) { this.fire('usersManagerUsersUpdate', params); },
	_usersManagerRequestsUpdate: function(params) { this.fire('usersManagerRequestsUpdate', params); }
	
});


